﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace TestGenerator
{
    class GenerateTest
    {
        private List<List<RealQuestion>> questionLists;

        private void GetTests()
        {
            TestParser parser = new TestParser(Settings.InputFilePath);
            List<QuestionSet> questionSetList = parser.Parse();

            if (questionSetList.Count < Settings.QuestionCount)
            {
                throw new ArgumentException("There are not enought questions");
            }

            Random rand = new Random();
            questionLists = new List<List<RealQuestion>>();

            for (int testNumber = 0; testNumber < Settings.NumberOfTests; testNumber++)
            {
                List<RealQuestion> realQuestionList = new List<RealQuestion>();

                for (int questionNumber = 0; questionNumber < Settings.QuestionCount; questionNumber++)
                {
                    HashSet<int> usedQuestions = new HashSet<int>();

                    int r;
                    do
                    {
                        r = rand.Next(questionSetList.Count);
                    }
                    while (usedQuestions.Contains(r));

                    usedQuestions.Add(r);

                    RealQuestion realQuestion = questionSetList[r].GetRandomQuestion();
                    realQuestionList.Add(realQuestion);
                }

                questionLists.Add(realQuestionList);
            }
        }

        private void GenHeader(int i, StreamWriter outputFile)
        {
            using (StreamReader inputFile = new StreamReader(Settings.InputFilePath, Encoding.Default))
            {
                string line = inputFile.ReadLine();
                while (line.IndexOf("</head>") < 0)
                {
                    outputFile.WriteLine(line);
                    line = inputFile.ReadLine();
                }
                StringBuilder lines = new StringBuilder();
                while (line.IndexOf("<table") < 0)
                {
                    lines.Append(line);
                    line = inputFile.ReadLine();
                }
                lines.Replace("# # #", string.Format("{0:000}", i));
                outputFile.WriteLine(lines);
            }
        }

        private void GenTable(StreamWriter outputFile)
        {
            outputFile.WriteLine("<div align=center>\n<table class=MsoNormalTable border=1 cellspacing=0 cellpadding=0" +
                "style='border-collapse:collapse;border:none'>\n<tr style='height:3.15pt'>\n");
            for (int i = 1; i < Settings.QuestionCount + 1; i++)
            {
                outputFile.WriteLine("<td width=28 style='width:16.6pt;border:solid windowtext 1.0pt;border-left:\n" +
                    "none;padding:2.85pt 0cm 2.85pt 0cm;height:3.15pt'>\n<p class=MsoNormal align=center style='text-align:center'>" +
                    "<span style='font-size:10.0pt'>&nbsp;</span></p>\n  </td>");
            }
            outputFile.WriteLine(" </tr>\n <tr style='height:3.15pt'>");
            for (int i = 1; i < Settings.QuestionCount + 1; i++)
            {
                outputFile.WriteLine(string.Format("<td width=28 style='width:16.6pt;border:solid windowtext 1.0pt;border-top:" +
                    "none;padding:2.85pt 0cm 2.85pt 0cm;height:3.15pt'>\n  <p class=MsoNormal align=center style='text-align:center'>" +
                    "<span style='font-size:10.0pt'>{0}</span></p>  </td>", i));
            }
            outputFile.WriteLine("</tr>\n</table>\n</div>");
        }

        private void GenQuestions(int i, StreamWriter outputFile)
        {
            int number = 1;
            foreach (RealQuestion question in questionLists[i])
            {
                outputFile.WriteLine("<p class=Question>" + number + ". " + question.Question + "</p>");
                number++;
                int answerLetter = 97;
                foreach (string answer in question.Answers)
                {
                    outputFile.WriteLine("<p class=Answer>" + (char)answerLetter + ") " + answer + "</p>");
                    answerLetter++;
                }
            }
        }

        private void GenFooter(StreamWriter outputFile)
        {
            int workTime = Settings.QuestionCount * 3;
            outputFile.WriteLine("<p class=MsoNormal style='margin-top:12.0pt'>Време за работа: " + workTime + " минути.</p>\n" +
                "<p class=MsoNormal>Успех на всички!</p>\n<p class=MsoNormal><b><span style='font-size:10.0pt'>&nbsp;</span></b></p>" +
                "</div>\n\n</body>\n\n</html>");
        }

        private void GenAnswers(StreamWriter outputFile)
        {
            const string header = "<html>\r\n\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1251\">\r\n<title>Test answers</title>\r\n\r\n<style>\r\n<!--\r\n /* Style Definitions */\r\np.MsoNormal, li.MsoNormal, div.MsoNormal\r\n\t{margin:0cm;\r\n\tmargin-bottom:.0001pt;\r\n\ttext-indent:1.0cm;\r\n\tfont-size:12.0pt;\r\n\tfont-family:\"Times New Roman\";}\r\nh1\r\n\t{margin-top:0cm;\r\n\tmargin-right:0cm;\r\n\tmargin-bottom:3.0pt;\r\n\tmargin-left:0cm;\r\n\ttext-align:center;\r\n\ttext-indent:1.0cm;\r\n\tpage-break-after:avoid;\r\n\tfont-size:22.0pt;\r\n\tfont-family:\"Times New Roman\";}\r\np.MsoHeader, li.MsoHeader, div.MsoHeader\r\n\t{margin:0cm;\r\n\tmargin-bottom:.0001pt;\r\n\ttext-indent:1.0cm;\r\n\tfont-size:12.0pt;\r\n\tfont-family:\"Times New Roman\";}\r\np.MsoFooter, li.MsoFooter, div.MsoFooter\r\n\t{margin:0cm;\r\n\tmargin-bottom:.0001pt;\r\n\ttext-indent:1.0cm;\r\n\tfont-size:12.0pt;\r\n\tfont-family:\"Times New Roman\";}\r\np.Question, li.Question, div.Question\r\n\t{margin-top:12.0pt;\r\n\tmargin-right:0cm;\r\n\tmargin-bottom:3.0pt;\r\n\tmargin-left:0cm;\r\n\ttext-align:justify;\r\n\tfont-size:12.0pt;\r\n\tfont-family:\"Times New Roman\";\r\n\tfont-weight:bold;}\r\np.Answer, li.Answer, div.Answer\r\n\t{margin-top:0cm;\r\n\tmargin-right:0cm;\r\n\tmargin-bottom:2.0pt;\r\n\tmargin-left:0cm;\r\n\ttext-align:justify;\r\n\ttext-indent:1.0cm;\r\n\tfont-size:12.0pt;\r\n\tfont-family:\"Times New Roman\";}\r\n@page Section1\r\n\t{size:595.3pt 841.9pt;\r\n\tmargin:42.55pt 1.0cm 2.0cm 1.0cm;}\r\ndiv.Section1\r\n\t{page:Section1;}\r\n-->\r\n</style>\r\n\r\n</head>\r\n\r\n<body lang=BG>\r\n\r\n<div class=Section1>\r\n\r\n<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0\r\n style='margin-left:.25pt;border-collapse:collapse;border:none'>\r\n ";
            const string TR_OPEN_TAG = "<tr style='height:3.15pt'>\r\n";
            const string TR_CLOSE_TAG = "</tr>\r\n";
            const string FIRST_COL_OPEN_TAG = "<td width=34 valign=top style='width:25.35pt;border:solid windowtext 1.0pt;\r\n padding:2.85pt 0cm 2.85pt 0cm;height:3.15pt'>\r\n <p class=MsoNormal align=center style='text-align:center;text-indent:0cm'><span \r\n style='font-size:10.0pt;font-family:Tahoma'>";
            const string FIRST_COL_CLOSE_TAG = "</span></p>\r\n </td>\r\n";
            const string OTHER_COLS_OPEN_TAG = "<td width=22 style='width:16.6pt;border:solid windowtext 1.0pt;border-left:\r\n none;padding:2.85pt 0cm 2.85pt 0cm;height:3.15pt'>\r\n <p class=MsoNormal align=center style='text-align:center;text-indent:0cm'\r\n ><span lang=EN-US style='font-size:10.0pt;font-family:Tahoma'>";
            const string OTHER_COLS_CLOSE_TAG = "</span></p>\r\n </td>\r\n";
            const string footer = "</table>\r\n\r\n <p class=Question>&nbsp;</p> \r\n\r\n </div> \r\n\r\n </body> \r\n\r\n </html>";
            using (outputFile)
            {
                outputFile.Write(header);
                outputFile.Write(TR_OPEN_TAG);
                outputFile.Write(FIRST_COL_OPEN_TAG);
                outputFile.Write("Вар.");
                outputFile.Write(FIRST_COL_CLOSE_TAG);
                for (int i = 0; i < Settings.QuestionCount; i++)
                {
                    outputFile.Write(OTHER_COLS_OPEN_TAG);
                    outputFile.Write(i + 1);
                    outputFile.Write(OTHER_COLS_CLOSE_TAG);
                }
                outputFile.Write(TR_CLOSE_TAG);
                for (int i = 0; i < Settings.NumberOfTests; i++)
                {
                    outputFile.Write(TR_OPEN_TAG);
                    outputFile.Write(FIRST_COL_OPEN_TAG);
                    outputFile.Write((i + 1).ToString().PadLeft(3, '0'));
                    outputFile.Write(FIRST_COL_CLOSE_TAG);
                    for (int j = 0; j < Settings.QuestionCount; j++)
                    {
                        outputFile.Write(OTHER_COLS_OPEN_TAG);
                        outputFile.Write((char)('a' + questionLists[i][j].CorrectAnswer));
                        outputFile.Write(OTHER_COLS_CLOSE_TAG);
                    }
                    outputFile.Write(TR_CLOSE_TAG);
                }
                outputFile.Write(footer);
            }
        }

        public void GenerateTests()
        {
            GetTests();
            for (int i = 1; i < Settings.NumberOfTests + 1; i++)
            {
                using (StreamWriter outputFile = new StreamWriter(string.Format("{0}{1:000}.html", Settings.OutputFileName, i),
                    false, Encoding.Default))
                {
                    GenHeader(i, outputFile);
                    GenTable(outputFile);
                    GenQuestions(i - 1, outputFile);
                    GenFooter(outputFile);
                }
            }
            GenAnswers(new StreamWriter(Settings.AnswersFile, false, Encoding.Default));
        }
    }
}
